package ru.elteam.web.beans.converters;

import org.apache.commons.lang3.text.StrTokenizer;
import ru.elteam.web.beans.request.AppearanceSettings;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;
import java.util.HashSet;
import java.util.Set;

/**
 * @author Nikita.Brazhnikov
 */
//@FacesConverter(forClass = AppearanceSettings.MessageViewFormat.class)
@FacesConverter(value = "elteam.convert.MessagesFormat")
public class ReportFormatConverter implements Converter {

	static Set<String> ALLOWED_KEYS = new HashSet<String>();

	static {
		ALLOWED_KEYS.add("reply");
		ALLOWED_KEYS.add("prlength");
	}

	@Override
	public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String s) {
		AppearanceSettings.MessageViewFormat format = new AppearanceSettings.MessageViewFormat();
		StrTokenizer tokenizer = new StrTokenizer(s, ' ');
		String[] tokens = tokenizer.getTokenArray();

		String currentKey = null;
		for (String token : tokens) {
			if (token.startsWith("-")) {
				if (currentKey != null)
					setValue(format, currentKey, null);
				String key = token.substring(1);
				if (!ALLOWED_KEYS.contains(key))
					errorKey(key);
				else
					currentKey = key;
			} else {
				if (currentKey == null)
					errorNoKey(token);
				else {
					setValue(format, currentKey, token);
					currentKey = null;
				}
			}
		}
		if (currentKey != null)
			setValue(format, currentKey, null);
		return format;
	}

	private void setValue(AppearanceSettings.MessageViewFormat format, String key, String value) {
		boolean notFound = false;
		try {
			if (key.equals("reply"))
				format.setAddReply(true);
			else if (key.equals("prlength")) {
				if (value == null)
					errorValue(null, "No value for key '" + key + "'");
				format.setPreviewLength(Integer.valueOf(value));
			} else
				notFound = true;
		} catch (Exception e) {
			errorValue(value, e.getLocalizedMessage());
		}
		if (notFound)
			errorKey(key);
	}

	private void errorValue(String value, String message) {
		FacesMessage msg = new FacesMessage();
		msg.setSeverity(FacesMessage.SEVERITY_ERROR);
		if (value != null)
			msg.setSummary("Conversation error: '" + value + "' is wrong (" + message + ")");
		else
			msg.setSummary(message);
		throw new ConverterException(msg);
	}

	private void errorNoKey(String value) {
		FacesMessage msg = new FacesMessage();
		msg.setSeverity(FacesMessage.SEVERITY_ERROR);
		msg.setSummary(value + " - key not found for value");
		throw new ConverterException(msg);
	}

	private void errorKey(String key) {
		FacesMessage msg = new FacesMessage();
		msg.setSeverity(FacesMessage.SEVERITY_ERROR);
		msg.setSummary("'" + key + "' is unknown key");
		throw new ConverterException(msg);
	}

	@Override
	public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object o) {
		AppearanceSettings.MessageViewFormat format = (AppearanceSettings.MessageViewFormat) o;
		StringBuilder sb = new StringBuilder();
		if (format.isAddReply())
			sb.append("-reply").append(" ");
		if (format.getPreviewLength() != null)
			sb.append("-prlength ").append(format.getPreviewLength());
		return sb.toString();
	}
}

